home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / asmutil / tedasm.zip / TED.ASM
Assembly Source File  |  1988-10-25  |  47KB  |  1,547 lines

  1. ;======================================================================
  2. ;  TED.ASM -- The Tiny EDitor.
  3. ;  PC Magazine * Tom Kihlken
  4. ;----------------------------------------------------------------------
  5. CSEG        SEGMENT
  6.         ASSUME    CS:CSEG, DS:CSEG, ES:CSEG
  7.         ORG    100H        ;Beginning for .COM programs
  8. START:
  9.         JMP    BEGIN
  10.  
  11. ;-----------------------------------------------------------------------
  12. ; Local data area
  13. ;-----------------------------------------------------------------------
  14. TAB        EQU    9
  15. CR        EQU    13
  16. LF        EQU    10
  17.  
  18. COPYRIGHT    DB    CR,LF,"TED 1.0 (c) 1988 Ziff Communications Co."
  19.         DB    CR,LF,"PC Magazine ",254," Tom Kihlken$",1AH
  20.  
  21. FILE_TOO_BIG    DB    "File too big$"
  22. READ_ERR_MESS    DB    "Read error$"
  23. MEMORY_ERROR    DB    "Not enough memory$"
  24.  
  25. PROMPT_STRING    DB    "1ABORT",0,"2UNDO",0,"3PRINT",0
  26.         DB    "4MARK",0,"5CUT",0,"6PASTE",0,"7EXIT",0
  27.         DB    "8DEL EOL",0,"9DEL L",0,"10UDEL L",0,0
  28. PROMPT_LENGTH    =    $ - OFFSET PROMPT_STRING
  29.  
  30. VERIFY_MESS    DB    "Lose Changes (Y/N)?",0
  31. SAVE_MESS    DB    "Save as: ",0
  32. DOT_$$$        DB    ".$$$",0
  33. DOT_BAK        DB    ".BAK",0
  34. DIRTY_BITS    DB    1
  35. NORMAL        DB    07H
  36. INVERSE        DB    70H
  37. LEFT_MARGIN    DB    0
  38. MARGIN_COUNT    DB    0
  39. INSERT_MODE    DB    -1
  40. MARK_MODE    DB    0
  41. ROWS        DB    23
  42. SAVE_COLUMN    DB    0
  43. SAVE_ROW    DB    0
  44. LINE_FLAG    DB    0
  45. EVEN
  46. NAME_POINTER    DW    81H
  47. NAME_END    DW    81H
  48. STATUS_REG    DW    ?
  49. VIDEO_SEG    DW    0B000H
  50. LINE_LENGTH    DW    0
  51. UNDO_LENGTH    DW    0
  52. CUR_POSN    DW    0
  53. MARK_START    DW    0FFFFH
  54. MARK_END    DW    0
  55. MARK_HOME    DW    0
  56. TOP_OF_SCREEN    DW    0
  57. CURSOR        DW    0
  58. LAST_CHAR    DW    0
  59. COLUMNSB    LABEL    BYTE
  60. COLUMNS        DW    ?
  61. PASTE_SEG    DW    ?
  62. PASTE_SIZE    DW    0
  63. PAGE_PROC    DW    ?
  64. OLDINT24    DD    ?
  65. DISPATCH_TABLE    DW    OFFSET ABORT    ,OFFSET UNDO   ,OFFSET PRINT
  66.         DW    OFFSET MARK    ,OFFSET CUT    ,OFFSET PASTE
  67.         DW    OFFSET EXIT    ,OFFSET DEL_EOL,OFFSET DEL_L
  68.         DW    OFFSET UDEL_L  ,OFFSET BAD_KEY,OFFSET BAD_KEY
  69.         DW    OFFSET HOME    ,OFFSET UP     ,OFFSET PGUP
  70.         DW    OFFSET BAD_KEY ,OFFSET LEFT   ,OFFSET BAD_KEY
  71.         DW    OFFSET RIGHT   ,OFFSET BAD_KEY,OFFSET ENDD
  72.         DW    OFFSET DOWN    ,OFFSET PGDN   ,OFFSET INSERT
  73.         DW    OFFSET DEL_CHAR
  74.  
  75. ; The following machine instruction removes the desnow delay.  It is
  76. ; inserted into the code for EGA, VGA, and MONO displays.
  77.  
  78. NO_DESNOW = 0EBH + (OFFSET WRITE_IT - OFFSET HWAIT - 2) * 256
  79.  
  80. ;-----------------------------------------------------------------------
  81. ; We start by initialize the display, then allocate memory for the file
  82. ; and paste segments.  Parse the command line for a filename, if one was
  83. ; input, read in the file.  Finally set the INT 23 and 24 vectors.
  84. ;-----------------------------------------------------------------------
  85. BEGIN:
  86.         XOR    AX,AX
  87.         MOV    DS,AX        ;Get a zero into DS
  88.         ASSUME    DS:NOTHING
  89.         MOV    AH,12H
  90.         MOV    BL,10H        ;Get EGA info
  91.         INT    10H
  92.         CMP    BL,10H        ;Did BL change?
  93.         JE    NOT_EGA        ;If not, no EGA in system
  94.         TEST    BYTE PTR DS:[0487H],8    ;Is EGA active?
  95.         JNZ    NOT_EGA
  96.         MOV    WORD PTR CS:HWAIT,NO_DESNOW ;Get rid of desnow
  97.         MOV    AX,DS:[0484H]    ;Get number of rows
  98.         DEC    AL        ;Last row is for prompt line
  99.          MOV    CS:[ROWS],AL    ;Save the number of rows
  100. NOT_EGA:
  101.         MOV    AX,DS:[044AH]    ;Get number of columns
  102.         MOV    CS:COLUMNS,AX    ;and store it
  103.         MOV    AX,DS:[0463H]    ;Address of display card
  104.         ADD    AX,6        ;Add six to get status port
  105.         PUSH    CS
  106.         POP    DS
  107.         ASSUME    DS:CSEG
  108.         MOV    STATUS_REG,AX
  109.         CMP    AX,3BAH        ;Is this a MONO display?
  110.         JNE    COLOR        ;If not, must be a CGA
  111.         MOV    WORD PTR HWAIT,NO_DESNOW ;Get rid of desnow
  112.         JMP    SHORT MOVE_STACK
  113. COLOR:
  114.         MOV    VIDEO_SEG,0B800H;Segment for color card
  115.         XOR    BH,BH        ;Use page zero
  116.         MOV    AH,8        ;Get current attribute
  117.         INT    10H
  118.         MOV    NORMAL,AH    ;Save the normal attribute
  119.         XOR    AH,1110111B    ;Flip the color bits
  120.         MOV    INVERSE,AH
  121. MOVE_STACK:
  122.         MOV    BX,OFFSET NEW_STACK
  123.         MOV    SP,BX        ;Move the stack downward
  124.         ADD    BX,15
  125.         MOV    CL,4        ;Convert program size to
  126.         SHR    BX,CL        ; paragraphs
  127.         MOV    AH,4AH        ;Deallocate unused memory
  128.         INT    21H
  129.         MOV    BX,1000H    ;Request 64K for file segment
  130.         MOV    AH,48H
  131.         INT    21H
  132.         MOV    ES,AX
  133.         ASSUME    ES:FILE_SEG
  134.         MOV    AH,48H
  135.         INT    21H        ;Request 64K for paste buffer
  136.         JNC    GOT_ENOUGH    ;If enough memory, continue
  137. NOT_ENOUGH:
  138.         MOV    DX,OFFSET MEMORY_ERROR
  139. ERR_EXIT:
  140.         PUSH    CS
  141.         POP    DS
  142.         MOV    AH,9        ;Write the error message
  143.         INT    21H        ;DOS display service
  144.         JMP    EXIT_TO_DOS    ;Exit this program
  145. GOT_ENOUGH:
  146.         MOV    PASTE_SEG,AX    ;Use this for the paste buffer
  147. GET_FILENAME:
  148.         MOV    SI,80H        ;Point to parameters
  149.         MOV    CL,[SI]        ;Get number of characters
  150.         XOR    CH,CH        ;Make it a word
  151.         INC    SI        ;Point to first character
  152.         PUSH    SI
  153.         ADD    SI,CX        ;Point to last character
  154.         MOV    BYTE PTR [SI],0    ;Make it an ASCII string
  155.         MOV    NAME_END,SI    ;Save pointer to last character
  156.         POP    SI        ;Get back pointer to filename
  157.         CLD
  158.         JCXZ    NO_FILENAME    ;If no params, just exit
  159. DEL_SPACES:    LODSB            ;Get character into AL
  160.         CMP    AL," "        ;Is it a space?
  161.         JNE    FOUND_LETTER
  162.         LOOP    DEL_SPACES
  163. FOUND_LETTER:
  164.         DEC    SI        ;Backup pointer to first letter
  165.         MOV    NAME_POINTER,SI    ;Save pointer to filename
  166.         MOV    DX,SI
  167.         MOV    AX,3D00H    ;Setup to open file
  168.         INT    21H
  169.         JC    NO_FILENAME     ;If we can't open, must be new file
  170. FILE_OPENED:
  171.         PUSH    ES
  172.         POP    DS        ;DS has file segment also
  173.         ASSUME    DS:FILE_SEG
  174.         MOV    BX,AX        ;Get the handle into BX
  175.         XOR    DX,DX        ;Point to file buffer
  176.         MOV    AH,3FH        ;Read service
  177.         MOV    CX,0FFFEH    ;Read almost 64K bytes
  178.         INT    21H
  179.         MOV    DI,AX        ;Number of bytes read in
  180.         JNC    LOOK_FOR_EOF    ;If no error, take jump
  181.         MOV    DX,OFFSET READ_ERR_MESS
  182.         JMP    SHORT ERR_EXIT
  183. LOOK_FOR_EOF:
  184.         CMP    BYTE PTR [DI-1],1AH ;Was last char an EOF mark?
  185.         JNE    NO_EOF        ;If not, everything is OK
  186.         DEC    DI        ;Backup to last character
  187. NO_EOF:
  188.         MOV    LAST_CHAR,DI    ;Save the file size
  189.         CMP    CX,AX        ;Did the buffer fill?
  190.         MOV    DX,OFFSET FILE_TOO_BIG
  191.         JE    ERR_EXIT    ;If yes, it is too big
  192.         MOV    AH,3EH
  193.         INT    21H        ;Close the file
  194. NO_FILENAME:
  195.         PUSH    ES
  196.         PUSH    ES        ;Save file segment
  197.         MOV    AX,3524H    ;Get INT 24 vector
  198.         INT    21H
  199.         MOV    WORD PTR OLDINT24,BX  ;Store the offset
  200.         MOV    WORD PTR OLDINT24+2,ES;And the segment
  201.  
  202.         PUSH    CS
  203.         POP    DS
  204.         MOV    DX,OFFSET NEWINT24    ;Point to new vector
  205.         MOV    AX,2524H    ;Now change INT 24 vector
  206.         INT    21H    
  207.  
  208.         MOV    DX,OFFSET NEWINT23
  209.         MOV    AX,2523H    ;Set the INT 23 vector also
  210.         INT    21H
  211.  
  212.         POP    ES        ;Get back file segment
  213.         POP    DS
  214.         ASSUME    DS:FILE_SEG, ES:FILE_SEG
  215.         CALL    REDO_PROMPT    ;Draw the prompt line
  216.  
  217. ;-----------------------------------------------------------------------
  218. ; Here's the main loop.  It updates the screen, then reads a keystroke.
  219. ;-----------------------------------------------------------------------
  220. READ_A_KEY:
  221.         CMP    MARK_MODE,0    ;Is the mark state on?
  222.         JE    MARK_OFF    ;If not, skip this
  223.         OR    DIRTY_BITS,4    ;Refresh the current row
  224.         MOV    DX,CUR_POSN
  225.         CMP    SAVE_ROW,DH    ;Are we on the save row?
  226.         JE    SAME_ROW    ;If yes, then redo the row only
  227.         MOV    DIRTY_BITS,1    ;Refresh the whole screen
  228. SAME_ROW:
  229.         MOV    AX,CURSOR    ;Get cursor location
  230.         MOV    BX,MARK_HOME    ;Get the anchor mark position
  231.         CMP    AX,BX        ;Moving backward in file?
  232.         JAE    S1
  233.         MOV    MARK_START,AX    ;Switch start and end position
  234.         MOV    MARK_END,BX
  235.         JMP    SHORT MARK_OFF
  236. S1:
  237.         MOV    MARK_END,AX    ;Store start and end marks
  238.         MOV    MARK_START,BX
  239. MARK_OFF:
  240.         MOV    DX,CUR_POSN
  241.         MOV    SAVE_ROW,DH
  242.         CALL    SET_CURSOR    ;Position the cursor
  243.         TEST    DIRTY_BITS,1    ;Look at screen dirty bit
  244.         JZ    SCREEN_OK    ;If zero, screen is OK
  245.  
  246.         MOV    AH,1        ;Get keyboard status
  247.         INT    16H        ;Any keys ready?
  248.         JNZ    CURRENT_OK    ;If yes, skip the update
  249.         CALL    DISPLAY_SCREEN    ;Redraw the screen
  250.         MOV    DIRTY_BITS,0    ;Mark screen as OK
  251. SCREEN_OK:
  252.         TEST    DIRTY_BITS,4    ;Is the current line dirty?
  253.         JZ    CURRENT_OK    ;If not, take jump
  254.         CALL    DISPLAY_CURRENT    ;Redraw the current line
  255.         MOV    DIRTY_BITS,0    ;Mark screen as OK
  256. CURRENT_OK:
  257.         XOR    AH,AH        ;Read the next key
  258.         INT    16H
  259.         OR    AL,AL        ;Is this an extended code?
  260.         JZ    EXTENDED_CODE
  261.         CMP    AH,0EH        ;Was it the backspace key?
  262.         JE    BACK_SPACE
  263.         CALL    INSERT_KEY    ;Put this character in the file
  264.         JMP    READ_A_KEY    ;Get another key
  265. BACK_SPACE:
  266.         CMP    CURSOR,0    ;At start of file?
  267.         JE    BAD_KEY        ;If at start, can't backspace
  268.         CALL    LEFT        ;Move left one space
  269.         CALL    DEL_CHAR    ;And delete the character
  270.         JMP    READ_A_KEY
  271. EXTENDED_CODE:
  272.         CMP    AH,84H        ;Is it control PgUp?
  273.         JNE    NOT_TOP
  274.         CALL    TOP
  275.         JMP